package com.xmutca.core.websocket;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by PETER on 2016/4/14.
 */
public class ChannelFactory {

    private final AttributeKey<String> auth = AttributeKey.valueOf("auth");

    private ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private Map<String, Set<Channel>> session = new HashMap<>();

    private WebSocketServerHandshaker handShaker;

    /**
     * 新用户注册
     * @param userId
     * @param channel
     */
    public void putSession(String userId, Channel channel) {
        //存储用户ID信息
        Attribute<String> attr = channel.attr(auth);
        attr.set(userId);

        //加入组
        group.add(channel);

        //设置用户的session
        Set<Channel> sessions = session.get(userId);
        if(sessions == null) {
            sessions = new HashSet<>();
        }
        sessions.add(channel);
        session.put(userId, sessions);
    }

    /**
     * 移除用户session
     * @param channel
     */
    public String removeSession(Channel channel){
        String userId = getUserId(channel);

        //从组中删除
        group.remove(channel);

        //移除session
        Set<Channel> sessions = session.get(userId);
        if(sessions != null) {
            sessions.remove(channel);
        }

        return userId;
    }

    /**
     * 获取用户的session列表
     * @param userId
     * @return
     */
    public Set<Channel> getSession(String userId) {
        return session.get(userId);
    }

    /**
     * 获取用户ID
     * @param channel
     * @return
     */
    public String getUserId(Channel channel) {
        Attribute<String> attr = channel.attr(auth);
        return attr.get();
    }

    /**
     * 关闭握手
     * @param ctx
     * @param frame
     */
    public void closeHandShaker(ChannelHandlerContext ctx, CloseWebSocketFrame frame) {
        getHandShaker().close(ctx.channel(), frame.retain());
    }

    /**
     * 连接握手
     * @param ctx
     * @param req
     */
    public void openHandshake(ChannelHandlerContext ctx, FullHttpRequest req) {
        getHandShaker().handshake(ctx.channel(), req);
    }

    public ChannelGroup getGroup() {
        return group;
    }

    public void setGroup(ChannelGroup group) {
        this.group = group;
    }

    public WebSocketServerHandshaker getHandShaker() {
        return handShaker;
    }

    public void setHandShaker(WebSocketServerHandshaker handShaker) {
        this.handShaker = handShaker;
    }
}